home *** CD-ROM | disk | FTP | other *** search
- page 58,132
- title fdread - lesen von disketten aller formate
-
- cseg segment word public 'device_dvr'
- assume cs:cseg
-
- org 0
- dd -1 ;Nur ein Driver
- dw 1000000000000000b ;Character-Device
- stra dw strategy ;Strategy-Routine
- entr dw entry ;Einsprungadresse
- IF MODE EQ 2
- db '&FDREAD2' ;Dummy-Name
- ELSE
- db '&FDREAD ' ;Dummy-Name
- ENDIF
-
- error proc far
- mov word ptr es:[bx+3],8103h ;Fehler, da nur Dummy-Device
- retf ;Ende
- error endp
-
- old13 label dword ;Speicherung des alten Interrupt 13
- old13_ofs dw ? ;Offset-Teil
- old13_seg dw ? ;Segment-Teil
- active db 1 ;bit 0 ON = active. (CJ)
-
- en proc far
- cmp ax,6368h ;Special call ("ch")? (CJ)
- jz spcl ;Maybe. (CJ)
- tstact: test byte ptr cs:active,01h ;Are we active? (CJ)
- jz exit ;Jump if not. (CJ)
- test dl,80h ;Floppy disk? (CJ)
- jnz exit ;Jump if not. (CJ)
- or ah,ah ;Wurde Funktion 0 RESET aufgerufen?
- jz exit ;Ja, dann Ende
- cmp ah,4 ;Wurde Funktion über 4 aufgerufen?
- ja exit ;Ja, dann Ende
- push ax ;Alle benötigten...
- push ds ;...Register...
- push bx ;...retten
- xor bx,bx
- mov ds,bx ;Setze auch DS=0
- lds bx,ds:[78h] ;Disk-Parameter Tabelle in DS:BX
- add al,cl ;Start sector + # sectors (CJ)
- dec al ;-1 = highest sector needed.(CJ)
- cmp al,ds:[bx+4] ;Enough sectors in table? (CJ)
- jna nochng ;Jump if yes. (CJ)
- mov ds:[bx+4],al ;Setze auf maximal 25 Sektoren/Spur
- nochng: pop bx ;Alle...
- pop ds ;...Register...
- pop ax ;...zurückholen.
- IF MODE EQ 2
- cmp dl,3 ;Laufwerk > 3
- ja exit ;Ja, dann Ende
- or ch,ch ;Track 0 ?
- jz exit ;Ja, dann Ende
- push ax ;AX für später speichern
- pushf ;Flags pushen da INT-CALL
- callpatch: call old13 ;Alten INT 13 aufrufen
- jnc okexit ;Kein Fehler, dann Ende
- pop ax ;Hole uns AX zurück
- push ds ;Speichere...
- push bx ;...DS & BX
- mov bx,40h ;Segment vom BIOS-RAM
- push bx ;von BX...
- pop ds ;...nach DS
- mov bx,90h ;Beginn der Drive-Tabelle
- add bl,dl ;Offset des Laufwerks
- cmp ch,43 ;Track>43
- ja nodstep ;Ja, dann niemals DSTEP
- xor byte ptr ds:[bx],20h ;invertiere das Stepper-Bit
- jmp short stepend ;Ende vom Stepping
- nodstep: and byte ptr ds:[bx],0dfh ;Kein Double-Stepping
- stepend: pop bx ;Hole BX und..
- pop ds ;...DS zurück
- ENDIF
- exit: jmp old13 ;Springe an den alten Interrupt 13
- IF MODE EQ 2
- okexit: inc sp ;Werfe den...
- inc sp ;...gesicherten AX weg
- ret 2 ;Und Ende mit original Flags
- ENDIF
- ;
- ; This routine, and other small changes have been made in this version by Crazy Jack
- ; in May, 1990. The changes are in the public domain. Some rearranging of the code
- ; in other areas was made to reduce the code size. This routine now responds ONLY to
- ; floppy disk I/O requests, and it adjusts the number of sectors in the FD table so
- ; that it never exceeds what the user is expecting. Using a fixed high value causes
- ; some programs (PCSHELL, for example) to be unable to format a disk while copying.
- ;
- ; Also added is a user interface. Into the AX register place the letters "ch" (the
- ; "c" goes in the ah, the "h" goes in the al), and place the characters "cj" into the
- ; DX register. Into the CL register place the new value that you want to store into the
- ; flag byte called "active". Then do an interrupt 13h (the BIOS disk services call).
- ; If FDREAD is not installed, this will result in an "invalid command" reply. If we
- ; ARE installed, you will get a clear carry flag, a zero in the AH register, and the
- ; PREVIOUS contents of the flag in the AL. You will also get the segment address of
- ; this program in the ES, and the offset to the "active" flag byte in the BX register.
- ;
- spcl: cmp dx,636Ah ;Rest of special signature ("cj")?
- jnz exit ;Jump if not. (CJ)
- push cs ;Return our segment address. (CJ)
- pop es ; (CJ)
- ofsact: mov bx,offset active ;Return address of flag. (CJ)
- mov al,es:[bx] ;Return current flag. (CJ)
- mov es:[bx],cl ;Set new flag value. (CJ)
- xor ah,ah ;Clear AH and CF. (CJ)
- sti ;...sure enuf! (CJ)
- ret 2 ;Done. (CJ)
- en endp
- savreq label dword ;DWORD zur...
- savreq_o dw ? ;...Sicherung des...
- savreq_s dw ? ;...Request Headers
-
- strategy proc far ;Strategy-Routine
- mov cs:[savreq_o],bx ;BX speichern
- mov cs:[savreq_s],es ;ES speichern
- ret ;...Fertig
- strategy endp
-
- entry proc far ;Einsprung Routine des Drivers
- assume cs:cseg
- push ax ;Alle Register und Flags retten
- push cx
- push dx
- push di
- push si
- push ds
- push es
- push bx
- pushf
- les bx,cs:[savreq] ;Hole den Request-Header
- mov al,es:[bx+2] ;Lade die Funktion
- cmp al,0 ;größer als 0
- jnz unkwn_com ;Ja, Fehler
- jmp short init ;Sonst initialisiere den Treiber
- entry endp
-
- rout proc far
- exit1: mov ax,100h ;Return ohne Fehler
- jmp short exgem
- unkwn_com: mov ax,8103h ;Unbekannter Befehl
- exgem: mov es:[bx+3],ax
- popf ;Alle Register wiederherstellen
- pop bx
- pop es
- pop ds
- pop si
- pop di
- pop dx
- pop cx
- pop ax
- ret
- rout endp ;und zurückgehen
-
-
- ;Die folgende Routine installiert FDR_OS2 als Device-Driver bei Einbindung
- ;in CONFIG.SYS mit dem DEVICE= Befehl
- ;HINWEIS: Auch unter DOS 4.xx oder OS/2 bitte mit DEVICE= installieren
-
- init: mov dx,offset text ;Lade Begrüßungstext
- mov ah,9 ;AH=9 für...
- int 21h ;...Ausgabe auf Bildschirm
- mov word ptr es:[bx+14],offset savreq ;Bis hier resident machen
- mov es:[bx+16],cs ;Segment auch abspeichern
- xor ax,ax ;AX auf Null setzen
- push ax ;Brauchen wir gleich nochmal
- mov ds,ax ;und DS=0 für Interrupt-Tabelle
- lds ax,ds:[13h*4] ;Lade alten Interrupt 13 in DS:BX
- mov cs:[old13_ofs],ax ;und speichere...
- mov cs:[old13_seg],ds ;...es ab.
- pop ds ;Nochmal DS=0
- mov word ptr ds:[13h*4],offset en ;Setze Offset von neuem INT 13
- mov ds:[13h*4+2],cs ;Setze Segment von neuem INT 13
- mov word ptr cs:[stra],offset error ;Alle Device-Driver-Requests...
- mov word ptr cs:[entr],offset error ;...mit UNKNOWN COMMAND beantowrten.
- jmp exit1 ;und schon fertig.
-
- IF MODE EQ 2
- text db 'FDREAD2 - Ver 1.20cj - Written by: C.Hochstätter & J.Armengaud',10,10,13,"$"
- ELSE
- text db 'FDREAD - Ver 1.20cj - Written by: C.Hochstätter',10,10,13,"$"
- ENDIF
- nimsg db 10,7,'FDREAD is not installed.',10,13,'$'
- fdonmsg db 'FDREAD is on',10,13,'$'
- fdoffmsg db 'FDREAD is off',10,13,'$'
-
- ;Die folgende Routine installiert FDR_OS2 bei Aufruf von der DOS-Kommandozeile.
- ;HINWEIS: Diese Installation ist nicht möglich unter OS/2
-
- exeinst: xor ax,ax ;AX=0
- IF MODE EQ 2
- mov word ptr cs:[callpatch+3],ax ;Relativer JUMP ist 0
- ENDIF
- mov word ptr cs:[exit+3],ax ;Ok, nicht besonders elegant
- ;(Don't EVER apologize for (CJ)
- ;things like that!!) (CJ)
- mov word ptr cs:[ofsact+1],offset active-offset old13 ;See? (CJ)
- mov word ptr cs:[tstact+3],offset active-offset old13 ; (CJ)
- mov ah,51h ;Hole den PSP...
- int 21h ;...in BX
- push bx ;Speichern...
- ; push bx THIS JUST CREATES A ;2 x
- ; pop ds SMALL, GENERALLY USELESS;...in DS
- ; mov es,ds:[2ch] HOLE IN RAM. LET'S ;Environment in ES holen
- ; mov ah,49h DROP IT FOR NOW. ;AH=49, um Environment
- ; int 21h ;freizugeben
- pop es ;PSP wieder in ES
- push cs ;DS mit Programm
- pop ds ;Segment laden
- ;
- ; We're gonna break in right here and see if there's a command line and see if
- ; we need to be installed.
- ;
- xor ch,ch ;First we scan the com- (CJ)
- mov cl,es:[128] ;mand tail. (CJ)
- mov di,129 ;Aim at start. (CJ)
- mov al,' ' ;Scan over any spaces. (CJ)
- cld ; (CJ)
- repe scasb ; (CJ)
- dec di ;Back up to character found(CJ)
- mov ax,es:[di] ;Pick up two of them. (CJ)
- or ax,2020h ;Force lower case. (CJ)
- cmp al,'o' ;Is the first one "o"? (CJ)
- jne noO ;Jump if not, (CJ)
- mov al,ah ;else get 2nd char. (CJ)
- noO: push es ;Save results and stuff. (CJ)
- push ax ; (CJ)
- mov ax,6368h ;Now see if we're (CJ)
- mov dx,636Ah ;already installed (CJ)
- mov cl,1 ;(try to change status). (CJ)
- int 13h ; (CJ)
- jnc alrdyin ;Jump if already installed.(CJ)
- pop ax ;Get restored. (CJ)
- pop es ; (CJ)
- cmp al,' ' ;Install? (CJ)
- je inwego ;Jump if yes.... (CJ)
- mov dx,offset nimsg ;Send error message. (CJ)
- mov ah,9 ; (CJ)
- int 21h ; (CJ)
- mov ax,4C69h ;Exit with not-zero (CJ)
- int 21h ;error level code. (CJ)
-
- alrdyin: mov cl,al ;Keep original setting. (CJ)
- pop ax ;Get back command. (CJ)
- cmp al,'n' ;Is command "on"? (CJ)
- jne tryf ;Jump if not, (CJ)
- mov cl,1 ;else set if to ON. (CJ)
- jmp short fdset ; (CJ)
- tryf: cmp al,'f' ;Okay, is it "off"? (CJ)
- jne showhat ;Jump if just display. (CJ)
- xor cl,cl ;Set it to OFF. (CJ)
- jmp short fdset ;Go set new value. (CJ)
-
- showhat: push cx ;Save switch value. (CJ)
- mov dx,offset fdonmsg ;Select 'off' or (CJ)
- or cl,cl ;"on" message as the (CJ)
- jnz pumpitout ;situation requires. (CJ)
- mov dx,offset fdoffmsg ; (CJ)
- pumpitout: mov ah,9 ; (CJ)
- int 21h ;Display the result. (CJ)
- pop cx ;Get back switch value. (CJ)
- fdset: mov ax,6368h ;Send it off to (CJ)
- mov dx,636Ah ;already installed (CJ)
- int 13h ;copy of FDREAD. (CJ)
- mov al,cl ;Return code = flag. (CJ)
- mov ah,4Ch ;Then do a benign (CJ)
- int 21h ;end of job. (CJ)
- ;
- ; --and now back to the installation code:
- ;
- inwego: mov dx,offset text ;Begrüßungstext laden
- mov ah,9 ;Und über INT 21...
- int 21h ;...auf Bildschirm ausgeben
- mov di,60h ;Hier können wir die Routine laden
- mov si,offset old13 ;Und zwar ab hier
- mov cx,(offset savreq-offset old13+1)/2 ;mit dieser Länge
- cld
- rep movsw ;Ok, verschiebe den Code
- mov ax,es ;Nun DS auf neues...
- add ax,6 ;...Segment...
- mov ds,ax ;...setzen.
- mov ax,3513h ;Lade die alte INT 13 Routine
- int 21h ;über DOS Call
- mov ds:[0],bx ;Speichere die Werte ab
- mov ds:[2],es ;Segment und Offset
- mov dx,offset en-offset old13 ;Beginn der Service-Routine
- mov ax,2513h ;Über DOS-Call
- int 21h ;installieren
- mov ax,3103h ;Wir bleiben speicherresident
- mov dx,(offset savreq-offset old13+15)/16+6;Anzahl der benötigten
- int 21h ;Paragraphen Und Ende
-
- cseg ends
- end exeinst
-